/*
 * オブジェクトマネージャ (object.c)
 */
#include <system.h>
#include <v93.h>
#include <nt.h>
#include <farl.h>
#include <agl.h>
#include <common.h>
#include "spec.h"
#include "vardecl.h"
#include "funcdecl.h"
#include "math.h"
#include "adpcm.h"

#ifndef LOCAL
#define LOCAL
#endif

/* 
----------------------------------------
  ローカル変数
----------------------------------------
*/
#define COL_COUNT (80)                /* 跳ね返り効果時間 */

LOCAL int ColCount;                /* 跳ね返り時間カウンタ */

LOCAL struct colloc {                /* 衝突した点 */
  float x;
  float y;
} colloc;
 
/* 
========================================
  衝突関係初期化
========================================
*/
void
InitCollision()
{
  int i;

  ColCount = 0;                        /* 跳ね返り時間カウンタ初期化 */
  for (i = 0; i < CORE_MAX; i++)
    destroy[i] = FALSE;                /* 破壊コアフラグ初期化 */
  destroyBoss = FALSE;
}

/* 
========================================
  地面描画
========================================
*/
void
DrawGround()
{
  register object *gp;
  int i;

  /* 地面のマトリクス計算・描画 */
  for (i = GROUND0; i < GROUND_MAX; i++) {
    gp = &Ground[i];
    /* オブジェクトマトリクス初期化 */
    AGLResetObj(gp);
    /* デフォルトカラー設定 */
    FarlSetDefColorReg(0x0801);
    /* スケール設定 */
    AGLScaleObj(gp, GroundScale, GroundScale, 1);
    /* 配置 */
    AGLTranslateObj(gp,
                    GroundLoc[i][LX],
                    GroundLoc[i][LY],
                    GroundLoc[i][LZ] + 4);
    /* 回転 */
    AGLRotateObjX(gp, 1800);
    /* 描画 */
    AGLFixPutObj(gp);
  }
}

/* 
----------------------------------------
  衝突判定サブ
----------------------------------------
*/
LOCAL boolean
colsub()
{
  tvector new[4];
  register machine *mp1, *mp2;
   float cos, sin;
  int i, dir;

  mp1 = &Machine[PLAYER1];
  mp2 = &Machine[PLAYER2];
  dir = (3600 + mp2->direct - mp1->direct) % 3600;
  cos = costbl[dir];
  sin = sintbl[dir];

  /* 正規化した PLAYER1 の座標にあわせて PLAYER2 の座標を回転・移動する */
  new[0].x = cos * (-mp2->type->width) - sin * mp2->type->h_plus +
      Locate[PLAYER2][LX] - Locate[PLAYER1][LX];
  new[0].y = sin * (-mp2->type->width) + cos * mp2->type->h_plus +
      Locate[PLAYER2][LY] - Locate[PLAYER1][LY];

  new[1].x = cos * mp2->type->width - sin * mp2->type->h_plus +
      Locate[PLAYER2][LX] - Locate[PLAYER1][LX];
  new[1].y = sin * mp2->type->width + cos * mp2->type->h_plus +
      Locate[PLAYER2][LY] - Locate[PLAYER1][LY];

  new[2].x = cos * (-mp2->type->width) - sin * mp2->type->h_minus + 
      Locate[PLAYER2][LX] - Locate[PLAYER1][LX];
  new[2].y = sin * (-mp2->type->width) + cos * mp2->type->h_minus +
      Locate[PLAYER2][LY] - Locate[PLAYER1][LY];

  new[3].x = cos * mp2->type->width - sin * mp2->type->h_minus +
      Locate[PLAYER2][LX] - Locate[PLAYER1][LX];
  new[3].y = sin * mp2->type->width + cos * mp2->type->h_minus +
      Locate[PLAYER2][LY] - Locate[PLAYER1][LY];

  for (i = 0; i < 4; i++) {
    /* PLAYER1の正規化した矩形内にPLAYER2 の頂点が侵入していたら衝突している */
    if (mp1->type->width >= new[i].x && mp1->type->h_plus >= new[i].y
        && new[i].x >= -mp1->type->width && new[i].y >= mp1->type->h_minus) {
      colloc.x = new[i].x;
      colloc.y = new[i].y;
      return TRUE;
    }
  }

  dir = (3600 + mp1->direct - mp2->direct) % 3600;
  cos = costbl[dir];
  sin = sintbl[dir];

  /* 正規化した PLAYER2 の座標にあわせて PLAYER1 の座標を回転・移動する */
  new[0].x = cos * (-mp1->type->width) - sin * mp1->type->h_plus +
      Locate[PLAYER1][LX] - Locate[PLAYER2][LX];
  new[0].y = sin * (-mp1->type->width) + cos * mp1->type->h_plus +
      Locate[PLAYER1][LY] - Locate[PLAYER2][LY];
  
  new[1].x = cos * mp1->type->width - sin * mp1->type->h_plus +
      Locate[PLAYER1][LX] - Locate[PLAYER2][LX];
  new[1].y = sin * mp1->type->width + cos * mp1->type->h_plus +
      Locate[PLAYER1][LY] - Locate[PLAYER2][LY];
  
  new[2].x = cos * (-mp1->type->width) - sin * mp1->type->h_minus +
      Locate[PLAYER1][LX] - Locate[PLAYER2][LX];
  new[2].y = sin * (-mp1->type->width) + cos * mp1->type->h_minus +
      Locate[PLAYER1][LY] - Locate[PLAYER2][LY];
  
  new[3].x = cos * mp1->type->width - sin * mp1->type->h_minus +
      Locate[PLAYER1][LX] - Locate[PLAYER2][LX];
  new[3].y = sin * mp1->type->width + cos * mp1->type->h_minus +
      Locate[PLAYER1][LY] - Locate[PLAYER2][LY];

  for (i = 0; i < 4; i++) {
    /* PLAYER2の正規化した矩形内にPLAYER1 の頂点が侵入していたら衝突している */
    if (mp2->type->width >= new[i].x && mp2->type->h_plus >= new[i].y
        && new[i].x >= -mp2->type->width && new[i].y >= mp2->type->h_minus) {
      colloc.x = new[i].x;
      colloc.y = new[i].y;
      return TRUE;
    }
  }

  return FALSE;
}

/*
----------------------------------------
  2個の物体の衝突
----------------------------------------
*/
LOCAL void
IfCollision()
{
  /* 衝突していれば */
  if (colsub()) {
    register machine *mp1, *mp2;
    float gammax1, gammay1, gammax2, gammay2;
    int i;

    /* 衝突効果時間のセット */
    ColCount = COL_COUNT;

    mp1 = &Machine[PLAYER1];
    mp2 = &Machine[PLAYER2];
    
    /* 相手の進行方向の加速度が加わる */
    mp1->colvec.x = mp1->type->Bounce * mp2->vector.x;
    mp1->colvec.y = mp1->type->Bounce * mp2->vector.y;
    mp2->colvec.x = mp2->type->Bounce * mp1->vector.x;
    mp2->colvec.y = mp2->type->Bounce * mp1->vector.y;

    /*
     * 衝突時の回転
     */
    for (i = PLAYER1; i < PLAYER_MAX; i++) {
      register machine *mp;
      float x, y;

      /* 衝突座標の正規化 */
      mp = &Machine[i];
      /* 原点回り逆回転 */
      x = costbl[mp->direct] * colloc.x + sintbl[mp->direct] * colloc.y; 
      y = costbl[mp->direct] * colloc.y - sintbl[mp->direct] * colloc.x; 

      if ((x > 0.0 && y > 0.0) || (x < 0.0 && y < 0.0)) { /* 第1,3象限 */
        mp->direct += mp->type->Handling * 2; /* 左回転 */
        x = costbl[mp->type->Handling * 2] * mp->vector.x
            - sintbl[mp->type->Handling * 2] * mp->vector.y;
        y = sintbl[mp->type->Handling * 2] * mp->vector.x
            + costbl[mp->type->Handling * 2] * mp->vector.y;
      } else { /* 第2,4象限 */
        mp->direct -= mp->type->Handling * 2; /* 右回転 */
        x = costbl[mp->type->Handling * 2] * mp->vector.x
            + sintbl[mp->type->Handling * 2] * mp->vector.y;
        y = -sintbl[mp->type->Handling * 2] * mp->vector.x
            + costbl[mp->type->Handling * 2] * mp->vector.y;
      }
      mp->vector.x = x;
      mp->vector.y = y;
      /* 角度修正 */
      if (mp->direct < 0)
        mp->direct += 3600;
      mp->direct %= 3600;
    }
    /*
     * 衝突音再生 合成ベクタの大きさによって違う音になる
     */
    {
      register machine *mp1, *mp2;
      int vec;
      int vel;

      mp1 = &Machine[PLAYER1];
      mp2 = &Machine[PLAYER2];
      vec = GETA_RAD * sqrt((mp1->vector.x + mp2->vector.x)
                 * (mp1->vector.x + mp2->vector.x)
                 + (mp1->vector.y + mp2->vector.y)
                 * (mp1->vector.y + mp2->vector.y));
      if (vec < 20)
        vel = 0;
      else if (vec < 50)
        vel = 2;
      else if (vec < 80)
        vel = 4;
      else
        vel = 6;
      AdpcmVolume(CHANNEL_1, MAX_PCM_VOLUME - vel, MAX_PCM_VOLUME - vel);
      AdpcmPlay(CHANNEL_1, &pInfo[P_HIT3]);
    }
  }
}

/*
========================================
  オブジェクト移動・衝突・落下
========================================
*/
boolean
ObjectMan()
{
  int i;

  IfCollision();
  for (i = PLAYER1; i < PLAYER_MAX; i++) {
    register machine *mp = &Machine[i];

    if (ColCount-- <= 0)
      ColCount = 0;
    if (ColCount == 0) {
      /* 衝突ベクタのリセット */
      mp->colvec.x = mp->colvec.y = mp->colvec.z = 0.0; 
    } else {
      /* 衝突ベクタ減衰 */
      mp->colvec.x = mp->colvec.x * ColCount / COL_COUNT;
      mp->colvec.y = mp->colvec.y * ColCount / COL_COUNT;
      mp->colvec.z = mp->colvec.z * ColCount / COL_COUNT;
      if (ColCount < COL_COUNT - 5 && ColCount > COL_COUNT - 9) {
        AdpcmVolume(CHANNEL_2, MAX_PCM_VOLUME, MAX_PCM_VOLUME);
        AdpcmPlay(CHANNEL_2, &pInfo[P_SLIP1]);
      }
    }
    /* 衝突ベクタの加算 */
    Locate[i][LX] += mp->colvec.x;
    Locate[i][LY] += mp->colvec.y;
    Locate[i][LZ] += mp->colvec.z;

    Locate[i][LX] += mp->vector.x; /* 移動ベクタによる X 座標の修正 */
    Locate[i][LY] += mp->vector.y; /* 移動ベクタによる Y 座標の修正 */
    Locate[i][LZ] += mp->vector.z; /* 移動ベクタによる Z 座標の修正 */
  }
  return IfFall();
}

/*
========================================
  オブジェクト描画

  引数
  rotx X回転角
  roty Y回転角
  which どちらのPLAYERを表示するか
       PLAYER1
       PLAYER2
  戻り値
  なし
========================================
*/
void
DrawObjects(int rotx, int roty, int which)
{
  register machine *mp;
  register object *gp;
  int i;

  /* 車のマトリクス計算 */
  mp = &Machine[which];
  AGLResetObj(&mp->type->obj);        /* オブジェクトマトリクス初期化 */
  FarlSetDefColorReg(mp->type->color);        /* デフォルトカラー設定 */
  
  /* スケール決定 */
  AGLScaleObj(&mp->type->obj, SCALE_CAR, SCALE_CAR, SCALE_CAR);
  /* 向き決定 */
  /* 落ちたほうだけ縦に回る */
  AGLRotateObjX(&mp->type->obj, 
    (900 + ((rotx > 0 && which == whichFall) ? rotx : 0)) % 3600); 
  AGLRotateObjY(&mp->type->obj,
    ((roty > 0 && which == whichFall) ? roty : 0)); 
  AGLRotateObjZ(&mp->type->obj, mp->direct);
  /* 位置決定 */
  AGLTranslateObj(&mp->type->obj,
                  FarlFix187(Locate[which][LX]),
                  FarlFix187(Locate[which][LY]),
                  FarlFix187(Locate[which][LZ]));
  /* 描画 */
  AGLFixPutObj(&mp->type->obj);
}

/************************************************************/
/************************************************************/

/* 
----------------------------------------
  ボスとの衝突判定 本体との衝突
----------------------------------------
*/
#define BOSS_CRAW_RATIO (0.9)

LOCAL boolean
BossColsub()
{
  static tvector new[4];
  register machine *mp1, *mp2;
  float cos, sin;
  int i, dir;

  mp1 = &Machine[PLAYER1];
  mp2 = &Machine[PLAYER2];

  /* コアの当り判定 */

  cos = costbl[3600 - mp1->direct];
  sin = sintbl[3600 - mp1->direct];

  for (i = 0; i < CORE_MAX; i++) {
    float x, y, cx, cy;
    float cos2, sin2;

    /* コアの現在位置を求める */
    cos2 = costbl[mp2->direct];
    sin2 = sintbl[mp2->direct];
    cx = cos2 * bosscoreLocate[i][LX] - sin2 * bosscoreLocate[i][LY];
    cy = sin2 * bosscoreLocate[i][LX] + cos2 * bosscoreLocate[i][LY];

    /* プレイヤーの座標を正規化するにともないコアの座標を移動する */
    x = cos * (cx - Locate[PLAYER1][LX]) - sin * (cy - Locate[PLAYER1][LY]);
    y = sin * (cx - Locate[PLAYER1][LX]) + cos * (cy - Locate[PLAYER1][LY]);

    /* プレイヤーの正規化した矩形内にコアの中心点が侵入していたら
       コアに衝突している */
    if (destroy[i] == FALSE
        && mp1->type->width >= x && mp1->type->h_plus >= y
        && x >= -mp1->type->width && y >= mp1->type->h_minus) {
      destroy[i] = TRUE;
      AdpcmVolume(CHANNEL_1, MAX_PCM_VOLUME, MAX_PCM_VOLUME);
      AdpcmPlay(CHANNEL_1, &pInfo[P_COREBREAK]);
      return TRUE;
    }
  }

  /* 本体の当り判定 */

  dir = (3600 + mp1->direct - mp2->direct) % 3600;
  cos = costbl[dir];
  sin = sintbl[dir];

  /* 正規化したボスの座標にあわせて PLAYER1 の座標を回転・移動する */
  new[0].x = cos * (-mp1->type->width) - sin * mp1->type->h_plus
          + Locate[PLAYER1][LX] - Locate[PLAYER2][LX];
  new[0].y = sin * (-mp1->type->width) + cos * mp1->type->h_plus
          + Locate[PLAYER1][LY] - Locate[PLAYER2][LY];
  
  new[1].x = cos * mp1->type->width - sin * mp1->type->h_plus
          + Locate[PLAYER1][LX] - Locate[PLAYER2][LX];
  new[1].y = sin * mp1->type->width + cos * mp1->type->h_plus
          + Locate[PLAYER1][LY] - Locate[PLAYER2][LY];
  
  new[2].x = cos * (-mp1->type->width) - sin * mp1->type->h_minus
          + Locate[PLAYER1][LX] - Locate[PLAYER2][LX];
  new[2].y = sin * (-mp1->type->width) + cos * mp1->type->h_minus
          + Locate[PLAYER1][LY] - Locate[PLAYER2][LY];
  
  new[3].x = cos * mp1->type->width - sin * mp1->type->h_minus
          + Locate[PLAYER1][LX] - Locate[PLAYER2][LX];
  new[3].y = sin * mp1->type->width + cos * mp1->type->h_minus
          + Locate[PLAYER1][LY] - Locate[PLAYER2][LY];

  for (i = 0; i < 4; i++) {
    /* ボスの正規化した本体矩形内にPLAYER1の頂点が侵入していたら衝突している */
    if (mp2->type->width * BOSS_BODY_RATIO >= new[i].x
        && mp2->type->h_plus * BOSS_BODY_RATIO >= new[i].y
        && new[i].x >= -mp2->type->width * BOSS_BODY_RATIO 
        && new[i].y >= mp2->type->h_minus * BOSS_BODY_RATIO) {
      colloc.x = new[i].x;
      colloc.y = new[i].y;
      return TRUE;
    }
  }

  /* 角の当り判定 */

  dir = (3600 + mp2->direct - mp1->direct) % 3600;
  cos = costbl[dir];
  sin = sintbl[dir];

  /* 正規化した PLAYER1 の座標にあわせてボスの座標を回転・移動する */
  new[0].x = cos * (-mp2->type->width) - sin * mp2->type->h_plus
          + Locate[PLAYER2][LX] - Locate[PLAYER1][LX];
  new[0].y = sin * (-mp2->type->width) + cos * mp2->type->h_plus
          + Locate[PLAYER2][LY] - Locate[PLAYER1][LY];
  
  new[1].x = cos * mp2->type->width - sin * mp2->type->h_plus
          + Locate[PLAYER2][LX] - Locate[PLAYER1][LX];
  new[1].y = sin * mp2->type->width + cos * mp2->type->h_plus
          + Locate[PLAYER2][LY] - Locate[PLAYER1][LY];
  
  new[2].x = cos * (-mp2->type->width) - sin * mp2->type->h_minus
          + Locate[PLAYER2][LX] - Locate[PLAYER1][LX];
  new[2].y = sin * (-mp2->type->width) + cos * mp2->type->h_minus
          + Locate[PLAYER2][LY] - Locate[PLAYER1][LY];
  
  new[3].x = cos * mp2->type->width - sin * mp2->type->h_minus
          + Locate[PLAYER2][LX] - Locate[PLAYER1][LX];
  new[3].y = sin * mp2->type->width + cos * mp2->type->h_minus
          + Locate[PLAYER2][LY] - Locate[PLAYER1][LY];

  for (i = 0; i < 4; i++) {
    /* PLAYER1 の正規化した矩形内に PLAYER2 の頂点が侵入していたら
       ボスの角が衝突している */
    if (mp1->type->width >= new[i].x * BOSS_CRAW_RATIO
        && mp1->type->h_plus >= new[i].y * BOSS_CRAW_RATIO
        && new[i].x >= -mp1->type->width * BOSS_CRAW_RATIO
        && new[i].y >= mp1->type->h_minus * BOSS_CRAW_RATIO) {
      colloc.x = new[i].x;
      colloc.y = new[i].y;
      return TRUE;
    }
  }


  return FALSE;
}

/* 
----------------------------------------
  ボスとの衝突
----------------------------------------
*/
LOCAL void
IfBossCollision()
{
  if (BossColsub()) {
    register machine *mp1, *mp2;
    float gammax1, gammay1, gammax2, gammay2;
    int i;

    /* 衝突効果時間のセット */
    ColCount = COL_COUNT;

    mp1 = &Machine[PLAYER1];        /* プレイヤー */
    mp2 = &Machine[PLAYER2];        /* ボス */
   
    /* 自分の加速度がボスの反射係数によって跳ね返る */
    mp1->colvec.x = mp2->type->Bounce * -mp1->vector.x;
    mp1->colvec.y = mp2->type->Bounce * -mp1->vector.y;
    /*
     * 衝突時の回転
     */
    for (i = PLAYER1; i < PLAYER_MAX; i++) {
      register machine *mp;
      float x, y;

      /* 衝突座標の正規化 */
      mp = &Machine[i];
      /* 原点回り逆回転 */
      x = costbl[mp->direct] * colloc.x + sintbl[mp->direct] * colloc.y; 
      y = costbl[mp->direct] * colloc.y - sintbl[mp->direct] * colloc.x; 

      if ((x > 0.0 && y > 0.0) || (x < 0.0 && y < 0.0)) { /* 第1,3象限 */
        mp->direct += mp->type->Handling * 2; /* 左回転 */
        x = costbl[mp->type->Handling * 2] * mp->vector.x
            - sintbl[mp->type->Handling * 2] * mp->vector.y;
        y = sintbl[mp->type->Handling * 2] * mp->vector.x
            + costbl[mp->type->Handling * 2] * mp->vector.y;
      } else { /* 第2,4象限 */
        mp->direct -= mp->type->Handling * 2; /* 右回転 */
        x = costbl[mp->type->Handling * 2] * mp->vector.x
            + sintbl[mp->type->Handling * 2] * mp->vector.y;
        y = -sintbl[mp->type->Handling * 2] * mp->vector.x
            + costbl[mp->type->Handling * 2] * mp->vector.y;
      }
      mp->vector.x = x;
      mp->vector.y = y;
      /* 角度修正 */
      if (mp->direct < 0)
        mp->direct += 3600;
      mp->direct %= 3600;
    }
    /*
     * 衝突音再生 合成ベクタの大きさによって違う音になる
     */
    {
      register machine *mp1, *mp2;
      int vec;
      int vel;

      mp1 = &Machine[PLAYER1];
      mp2 = &Machine[PLAYER2];
      vec = GETA_RAD * sqrt((mp1->vector.x + mp2->vector.x)
            * (mp1->vector.x + mp2->vector.x)
            + (mp1->vector.y + mp2->vector.y) 
            * (mp1->vector.y + mp2->vector.y));
      if (vec < 20)
        vel = 0;
      else if (vec < 50)
        vel = 2;
      else if (vec < 80)
        vel = 4;
      else
        vel = 6;
      AdpcmVolume(CHANNEL_1, MAX_PCM_VOLUME - vel, MAX_PCM_VOLUME - vel);
      AdpcmPlay(CHANNEL_1, &pInfo[P_HIT3]);
    }
  }
}

/* 
========================================
  ボスラウンド用オブジェクトマネージャ
========================================
*/
boolean
BossObjectMan()
{
  /* 衝突による移動対象はプレイヤーのみ */
  register machine *mp = &Machine[PLAYER1]; 
  int i;

  IfBossCollision();

  if (ColCount-- <= 0)
    ColCount = 0;
  if (ColCount == 0) {
    /* 衝突ベクタのリセット */
    mp->colvec.x = mp->colvec.y = mp->colvec.z = 0.0; 
  } else {
    /* 衝突ベクタ減衰 */
    mp->colvec.x = mp->colvec.x * ColCount / COL_COUNT;
    mp->colvec.y = mp->colvec.y * ColCount / COL_COUNT;
    mp->colvec.z = mp->colvec.z * ColCount / COL_COUNT;
    if (ColCount < COL_COUNT - 5 && ColCount > COL_COUNT - 9) {
      AdpcmVolume(CHANNEL_2, MAX_PCM_VOLUME, MAX_PCM_VOLUME);
      AdpcmPlay(CHANNEL_2, &pInfo[P_SLIP1]);
    }
  }
  /* 衝突ベクタの加算 跳ね返るのはプレイヤーのみ */
  Locate[PLAYER1][LX] += mp->colvec.x;
  Locate[PLAYER1][LY] += mp->colvec.y;
  Locate[PLAYER1][LZ] += mp->colvec.z;
  
  Locate[PLAYER1][LX] += mp->vector.x; /* 移動ベクタによる X 座標の修正 */
  Locate[PLAYER1][LY] += mp->vector.y; /* 移動ベクタによる Y 座標の修正 */
  Locate[PLAYER1][LZ] += mp->vector.z; /* 移動ベクタによる Z 座標の修正 */

  {
    int i, count;

    /* コアはすべて破壊されたか */
    for (count = 0, i = 0; i < CORE_MAX; i++) {        
      if (destroy[i] == TRUE)
        count++;
    }
    if (count == CORE_MAX) {
      destroyBoss = TRUE;        /* ボスは破壊された */
      return TRUE;
    }
    destroyBoss = FALSE;
  }
  return IfFall();                /* プレイヤーが落ちたか */
}

/* 
========================================
  ボスラウンド用オブジェクト描画
========================================
*/
void
BossDrawObjects()
{
  register machine *mp;
  register object *gp;
  int i, which;

  /* ボス本体のマトリクス計算 */
  mp = &Machine[PLAYER2];
  AGLResetObj(&mp->type->obj); /* オブジェクトマトリクス初期化 */
  FarlSetDefColorReg(mp->type->color); /* デフォルトカラー設定 */

  /* スケール決定 */
  AGLScaleObj(&mp->type->obj, SCALE_CAR, SCALE_CAR, SCALE_CAR);
  /* 向き決定 */
  AGLRotateObjX(&mp->type->obj, 900);
  AGLRotateObjZ(&mp->type->obj, mp->direct);
  /* 位置決定 */
  AGLTranslateObj(&mp->type->obj,
                  FarlFix187(Locate[PLAYER2][LX]),
                  FarlFix187(Locate[PLAYER2][LY]),
                  FarlFix187(Locate[PLAYER2][LZ]));
  /* 描画 */
  AGLFixPutObj(&mp->type->obj);

  /* ボスコアマトリクス計算・表示 */
  for (i = 0; i < CORE_MAX; i++) {
    static object Obj;
    int dir;
    float cos, sin;

    if (destroy[i] == TRUE)        /* コアが破壊されていたら表示しない */
      continue;

    Obj.geometryTop = (int *)bosscore;
    Obj.geometryLength = bosscoreLength;
    Obj.material = &groundMaterial;

    dir = Machine[PLAYER2].direct;
    cos = costbl[dir];
    sin = sintbl[dir];

    AGLResetObj(&Obj);
    FarlSetDefColorReg(0x0505);        /* 赤 */
    AGLScaleObj(&Obj, 0x4, 0x4, 0x4);
    AGLRotateObjX(&Obj, 900);
    AGLRotateObjZ(&Obj, dir);
    AGLTranslateObj(&Obj, 
        FarlFix187(cos * bosscoreLocate[i][LX] - sin * bosscoreLocate[i][LY]),
        FarlFix187(sin * bosscoreLocate[i][LX] + cos * bosscoreLocate[i][LY]),
        FarlFix187(bosscoreLocate[i][LZ])
        );
    AGLFixPutObj(&Obj);
  }
  
  DrawGround();                        /* 地面描画 */
}
